package swardToOffer.regularExpressions;

/**
 * @Author ChanZany
 * @Date 2021/5/21 10:23
 * @Version 1.0
 面试题20：表示数值的字符串
 题目：请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。例如，
 字符串“+100”、“5e2”、“-123”、“3.1416”及“-1E-16”都表示数值，但“12e”、
 “1a3.14”、“1.2.3”、“+-5”及“12e+5.4”都不是

 分析：表示数字的字符串遵循模式A[.[B]][e|EC] 或者是.B[e|EC]
 其中A为数值的整数部分(可正可负)，B为数值的小数部分（只能正），C是'e|E'后的指数部分（可正可负）
 以 123.45e+6为例： A=123,B=45,C=+6
 */
public class NumericStrings {
    boolean isNumeric(String str){
        if (str == null || str.length()==0) return false;
        //去掉首位空格
        str = str.trim();
        boolean numFlag = false;
        boolean dotFlag = false;
        boolean eFlag = false;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i)>='0' && str.charAt(i)<='9'){
                numFlag = true;
            }
            // 判定为 . 需要没出现过 . 且没有出现过 e
            else if (str.charAt(i)=='.' && !dotFlag && !eFlag){
                dotFlag = true;
            }
            // 判定为 e 需要没出现过 e 并且有数字出现
            else if ((str.charAt(i)=='e' || str.charAt(i)=='E') && !eFlag && numFlag){
                eFlag = true;
                numFlag = false;
            }
            // 判定 +- 只能出现在第一位或紧跟着e后面
            else if ((str.charAt(i) == '+' || str.charAt(i) == '-') &&
                    (i == 0 || str.charAt(i - 1) == 'e' || str.charAt(i - 1) == 'E')) {
            }
            // 其他情况都是非法的
            else {
                return false;
            }

        }
        return numFlag;
    }



    public static void main(String[] args) {
        NumericStrings Main = new NumericStrings();
        System.out.println(Main.isNumeric("123.45e+6"));
        System.out.println(Main.isNumeric("12e+5.4"));
    }
}
